from rest_framework import serializers
from course.models import Course
from rest_framework.exceptions import ValidationError
from utils.exception import MyException
from .models import Order,OrderDetail
import uuid
from django.conf import settings
from lib.al_pay import alipay,gateway
class PayOrderSerializer(serializers.ModelSerializer):
    # 用户传入的是courses:[1,2,3]==转成课程对象==》[obj1,obj2,obj3]
    # courses:[1,2,3]---->PrimaryKeyRelatedField--->指定queryset，会去queryset中过滤，主键为[1,2,3]的课程
    courses = serializers.PrimaryKeyRelatedField(queryset=Course.objects.all(), many=True, write_only=True)

    # user=serializers.PrimaryKeyRelatedField(queryset=User.objects.all(),many=False)
    class Meta:
        model = Order
        # 从前端传过来(订单号后端生成)
        '''
          {'subject':'python从入门到精通',
            total_amount:100,
            pay_type：1 (支付类型，目前只有支付宝)，
            courses:[1,2,3] 课程id号
         }
        '''
        fields = ['subject', 'total_amount', 'pay_type', 'courses']
        extra_kwargs = {
            'total_amount': {'required': True, }
        }

    def _check_price(self, attrs):
        courses = attrs.get('courses')
        total = 0
        for course in courses:
            total += course.price
        if not total == attrs.get('total_amount'):
            raise MyException('钱数不合法')

    def _get_order_no(self):
        order_no=str(uuid.uuid4())
        return order_no.replace('-','')

    def _get_user(self):
        user=self.context.get('request').user
        return user

    def _gen_pay_url(self,attrs,order_no):

        order_string = alipay.api_alipay_trade_page_pay(
            out_trade_no=order_no,
            total_amount=float(attrs.get('total_amount')), # 转成浮点型
            subject=attrs.get('subject'),
            # 写在配置文件中
            return_url=settings.RETURN_URL,
            notify_url=settings.NOTIFY_URL
        )
        return gateway+order_string

    def _pre_create(self,attrs,user,order_no):
        # 把用户，订单状态，订单号，写入attrs
        attrs['order_status']=0
        attrs['user']=user
        attrs['out_trade_no']=order_no



    def validate(self, attrs):
        # 1）订单总价校验
        self._check_price(attrs)
        # 2）生成订单号
        order_no=self._get_order_no()
        # 3）支付用户：request.user
        user=self._get_user()
        # 4）支付链接生成
        pay_url=self._gen_pay_url(attrs,order_no)
        self.context['pay_url']=pay_url
        # 5）入库(两个表)的信息准备（重写create方法）
        self._pre_create(attrs,user,order_no)
        return attrs

    def create(self, validated_data):
        # 存两个表
        # course需要存detail表
        courses=validated_data.pop('courses')
        # 开启一个事务
        order=Order.objects.create(**validated_data)
        for course in courses:
            OrderDetail.objects.create(order=order,course=course,price=course.price,real_price=course.price)

        return order
